知识点名称:Android音频播放技术

编号: K8-4

前驱知识点编号:K4-1,K3-1,K3-2

作者:

讲义内容:

8.5.1 Android音频播放基本概念

音频采样的基本过程,它将连续的声音波形转换成为若干范围内的离散数值,从而将音频数据用二进制的形式在计算机系统中表示。

编码器负责将原始数据进行一定的前期处理,比如压缩算法以减小体积,然后才以某种特定的文件格式进行保存。文件格式(FileFormat)和文件编码器(Codec)是两个不同的概念,例如常见的音频文件格式AVI就支持多种音频和视频编码方式。

数字音频格式分为以下几种:

1、不压缩的格式(UnCompressed Audio Format)

PCM数据,就是采样后得到的未经压缩的数据。PCM数据在Windows和Mac系统上通常分别以wav和aiff后缀进行存储。可这样的文件大小是比较可观的。

2、无损压缩格式(Lossless Compressed Audio Format)

这种压缩的前提是不破坏音频信息,也就是说后期可以完整还原出原始数据。同时它在一定程度上可以减小文件体积。比如FLAC、APE(Monkey’sAudio)、WV(WavPack)、m4a(Apple Lossless)等等

3、有损压缩格式(Lossy Compressed Audio Format)

无损压缩技术能减小的文件体积相对有限,因而在满足一定音质要求的情况下,还可以进行有损压缩。如mp3格式,另外还有iTunes上使用的AAC,这些格式通常可以指定压缩的比率——比率越大,文件体积越小,但效果也越差。至于采用哪一种格式,通常要视具体的使用场景而定。

Android下的音频播放有多种方式,经常使用的方法有MediaPlayer类和SoundPool类。MediaPlayer类适合播放较大文件,也是经常使用的音频播放方法,但它也存在一些不足,例如:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。而在游戏开发中,经常需要播放一些游戏音效(比如:子弹爆炸,物体撞击等),这些音效的共同特点是短促、密集、延迟程度小。在这样的场景下,可以使用SoundPool代替MediaPlayer。

下载的音频文件可以将其放入assets文件夹下或者res下的raw文件夹下,区别在于assets下可以再新建文件夹而raw不行,assets内部单个文件超过1m时可能存在bug而raw不会。

8.5.2 MediaPlayer播放音频

MediaPlayer类是Androd多媒体框架中的一个重要组件,位于android.media包下,通过该类,我们可以以最小的步骤来获取,解码和播放音视频。它支持三种不同的媒体来源:

(1)本地资源

(2)内部URI,比如你可以通过ContentResolver来获取

(3)外部URL(流)

相关方法详解

(1)获得MediaPlayer实例:

可以直接new或者调用create方法创建:

MediaPlayer mp = new MediaPlayer();
MediaPlayer mp = MediaPlayer.create(this, R.raw.test); //无需再调用setDataSource

另外create还有这样的形式:

create(Context context, Uri uri, SurfaceHolder holder)

通过Uri和指定 SurfaceHolder 【抽象类】 创建一个多媒体播放器。

(2)设置播放文件:

MediaPlayer.create(this, R.raw.test); //①raw下的资源
mp.setDataSource("/sdcard/test.mp3"); //②本地文件路径
mp.setDataSource("http://www.xxx.com/music/test.mp3");//③网络URL文件

另外setDataSource()方法有多个,里面有这样一个类型的参数:FileDescriptor

在使用这个API的时候,需要把文件放到res文件夹平级的assets文件夹里,然后使用下述代码设置DataSource:

AssetFileDescriptor fileDescriptor = getAssets().openFd("rain.mp3"); 
mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),fileDescriptor.getStartOffset(), fileDescriptor.getLength());

(3)其他方法

  • getCurrentPosition( ):得到当前的播放位置
  • getDuration() :得到文件的时间
  • getVideoHeight() :得到视频高度
  • getVideoWidth() :得到视频宽度
  • isLooping():是否循环播放
  • isPlaying():是否正在播放
  • pause():暂停
  • prepare():准备(同步)
  • prepareAsync():准备(异步)
  • release():释放MediaPlayer对象
  • reset():重置MediaPlayer对象
  • seekTo(int msec):指定播放的位置(以毫秒为单位的时间)
  • setAudioStreamType(int streamtype):指定流媒体的类型
  • setDisplay(SurfaceHolder sh):设置用SurfaceHolder来显示多媒体
  • setLooping(boolean looping):设置是否循环播放
  • setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener):网络流媒体的缓冲监听
  • setOnCompletionListener(MediaPlayer.OnCompletionListener listener):网络流媒体播放结束监听
  • setOnErrorListener(MediaPlayer.OnErrorListener listener):设置错误信息监听
  • setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener):视频尺寸监听
  • setScreenOnWhilePlaying(boolean screenOn):设置是否使用SurfaceHolder显示
  • setVolume(float leftVolume, float rightVolume):设置音量
  • start():开始播放
  • stop():停止播放

MediaPlayer主要用于播放音频,没有提供图像输出界面,需要借助其他的组件来显示MediaPlayer播放的图像输出,可以使用SurfaceView来显示。

8.5.3 SoundPool播放音频

SoundPool的使用步骤是 :

1.在res中新建raw文件夹,然后将需要播放的音频放入其中;

2.初始化SoundPool实例;

3.调用SoundPool的play函数进行播放。

几个重要的函数:

soundPool的构造函数

public SoundPool (int maxStreams, int streamType, int srcQuality)

参数:

maxStreams 同时最大播放音频个数

streamType 音频流的类型,通常使用 STREAM_MUSIC.

srcQuality the sample-rate converter quality. Currently has no effect. Use 0 for the default.

音效播放函数:

public void playSounds(int sound, int number){
//实例化AudioManager对象,控制声音
AudioManager am = (AudioManager)this.getSystemService(this.AUDIO_SERVICE);
//最大音量
float audioMaxVolumn = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
//当前音量
float audioCurrentVolumn = am.getStreamVolume(AudioManager.STREAM_MUSIC);
float volumnRatio = audioCurrentVolumn/audioMaxVolumn;
//播放
sp.play(spMap.get(sound), //声音资源
volumnRatio, //左声道
volumnRatio, //右声道
1, //优先级,0最低
number, //循环次数,0是不循环,-1是永远循环
1); //回放速度,0.5-2.0之间。1为正常速度

results matching ""

    No results matching ""